package com.itany.mall.jdbc.util;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSourceFactory;

import com.itany.mall.jdbc.exception.DataAccessException;

/**
 * JDBC工具类
 * @author 赵云
 */
public class JDBCUtil {

	private static final DataSource DATASOURCE;

	// Connection对象, 对于同一线程而言, 应当是单例的
	// 但对于不同线程而言, 应当是非单例的
	private static final ThreadLocal<Connection> THREADLOCAL;

	static {
		THREADLOCAL = new ThreadLocal<Connection>();
		Properties properties = new Properties();
		try {
			properties.load(
					JDBCUtil.class.getClassLoader().getResourceAsStream("datasource.properties"));

			DATASOURCE = BasicDataSourceFactory.createDataSource(properties);

		} catch (Exception e) {
			e.printStackTrace();
			throw new ExceptionInInitializerError("JDBCUtil初始化失败");
		}
	}

	/**
	 * 获取数据库连接对象
	 * @return 数据库连接对象
	 */
	public static final Connection getConnection() {
		try {
			Connection con = THREADLOCAL.get();
			if (con == null) {
				con = DATASOURCE.getConnection();
				THREADLOCAL.set(con);
			}
			return con;
		} catch (Exception e) {
			throw new DataAccessException("数据库连接失败", e);
		}
	}

	/**
	 * 关闭相关资源
	 * @param res ResultSet对象
	 * @param st Statement对象
	 * @param con Connection对象
	 */
	public static final void close(ResultSet res, Statement st, Connection con) {
		try {
			if (res != null)
				res.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (st != null)
					st.close();
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				try {
					if (con != null) {
						con.close();
						// 当数据库连接释放, Connection对象应当从线程单例中移除
						// 因为不移除的话, 连接对象回不到数据源连接池中
						THREADLOCAL.remove();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

}
